package net.xo68.destiny.core.timingwheel.impl;

import lombok.extern.slf4j.Slf4j;
import net.xo68.destiny.core.timingwheel.TimingWheelTaskExecutor;
import net.xo68.destiny.core.util.ThreadUtils;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

/**
 * 时光轮任务执行器
 * @author wuxie
 * @version 2020-10-19
 */
@Slf4j
public class DefaultTimingWheelTaskExecutor implements TimingWheelTaskExecutor {

    private final ExecutorService executorService;
    private final int threadCount;

    public DefaultTimingWheelTaskExecutor(String threadPrefix,int threadCount) {
        this.threadCount=normalizeThreadCount(threadCount);
        this.executorService = ThreadUtils.newFixedThreadPool(threadPrefix,this.threadCount);
        log.info("时光轮任务执行器：线程前缀：{}, 线程数：{}",threadPrefix,this.threadCount);
    }

    @Override
    public Future<?> submit(Runnable task) {
        return this.executorService.submit(task);
    }

    @Override
    public <T> Future<T> submit(Callable<T> task) {
        return this.executorService.submit(task);
    }

    @Override
    public void shutdown() {
        this.executorService.shutdown();
    }

    @Override
    public List<Runnable> shutdownNow() {
        return this.executorService.shutdownNow();
    }

    /**
     * 修正超时项任务执行线程池的线程数
     * @param threadCount
     * @return
     */
    private static int normalizeThreadCount(int threadCount) {
        int normalizedThreadCount = threadCount;
        if(threadCount<=0){
            normalizedThreadCount=Runtime.getRuntime().availableProcessors()*2;
        }else if(threadCount > Runtime.getRuntime().availableProcessors()*3) {
            normalizedThreadCount=Runtime.getRuntime().availableProcessors()*3;
        }
        return normalizedThreadCount;
    }
}
